package com.yanlin.serviceprice.service;

import com.yanlin.internalcommon.dto.ResponseResult;
import com.yanlin.internalcommon.request.ForecastPriceDTO;
import com.yanlin.internalcommon.response.DicDirectionResponse;
import com.yanlin.internalcommon.response.ForecastPriceResponse;
import com.yanlin.serviceprice.dto.PriceRule;
import com.yanlin.serviceprice.mapper.PriceRuleMapper;
import com.yanlin.serviceprice.remote.ServiceMapClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.RoundingMode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.yanlin.internalcommon.constant.CommonStatusEnum.PRICE_RULE_ERROR;
import static com.yanlin.internalcommon.util.BigDecimalUtils.*;

/**
 * <p>标题：ForecastPriceService</p>
 * <p>功能：计价规则</p>
 * <p>
 * 其他说明：
 * </p>
 * <p>审核：</p>
 * <p>重构：</p>
 * <p>创建日期：2025-06-09 16:10</p>
 *
 * @author yanlin
 */
@Slf4j
@Service
public class ForecastPriceService {

    @Autowired
    private ServiceMapClient serviceMapClient;
    @Autowired
    private PriceRuleMapper priceRuleMapper;

    public ResponseResult forecastPrice(String depLongitude, String depLatitude, String destLongitude, String destLatitude) {

        // 调用地图服务 计价服务，计算价格
        ForecastPriceDTO forecastPriceDTO = new ForecastPriceDTO();
        forecastPriceDTO.setDepLongitude(depLongitude);
        forecastPriceDTO.setDepLatitude(depLatitude);
        forecastPriceDTO.setDestLongitude(destLongitude);
        forecastPriceDTO.setDestLatitude(destLatitude);
        ResponseResult<DicDirectionResponse> direction = serviceMapClient.direction(forecastPriceDTO);
        Integer distance = direction.getData().getDistance();
        Integer duration = direction.getData().getDuration();
        log.debug("距离 = {}, 时长 = {}",distance, duration);
        // 读取计价规则
        Map<String, Object> map = new HashMap<>();
        map.put("city_code", "110000");
        map.put("vehicle_type", "1");
        List<PriceRule> priceRules = priceRuleMapper.selectByMap(map);
        if (priceRules.size() == 0) {
            return ResponseResult.fail(PRICE_RULE_ERROR.getCode(), PRICE_RULE_ERROR.getValue());
        }
        PriceRule priceRule = priceRules.get(0);
        // 根据距离、时长和计价规则，计算价格
        double price = calcPrice(distance, duration, priceRule);

        ForecastPriceResponse forecastPriceResponse = new ForecastPriceResponse();
        forecastPriceResponse.setPrice(price);
        return ResponseResult.success(forecastPriceResponse);
    }

    /**
     * 根据距离、时长、规则计算价格
     * @param totalDistance 距离
     * @param duration 时长
     * @param priceRule 计价规则
     * @return
     */
    private static double calcPrice(Integer totalDistance, Integer totalDuration, PriceRule priceRule) {

        double price = 0.00;

        // 起步价
        price = add(price, priceRule.getStartFare());
        // 里程转换m -> km && 时长转换s -> m
        double distance_ = divide(totalDistance, 1000);
        double duration_ = divide(totalDuration, 60);
        // 求得计价里程
        double distance = substract(distance_, priceRule.getStartMile());
        if (distance > 0) {
            // 里程费
            double priceDistance = multiply(distance, priceRule.getUnitPricePerMile());
            price = add(price, priceDistance);
            // 时长费
            double priceDuration = multiply(duration_, priceRule.getUnitPricePerMinute());
            price = add(price, priceDuration);
        }
        // 精确到2位小数
        price = setScale(price, 2, RoundingMode.HALF_UP);
        return price;
    }

    private static class MainTest{

        public static void main(String[] args) {
            PriceRule priceRule = new PriceRule();
            priceRule.setStartFare(6);
            priceRule.setStartMile(1);
            priceRule.setUnitPricePerMile(6);
            priceRule.setUnitPricePerMinute(1);
            double price = calcPrice(3800, 1800, priceRule);
            System.out.println("总价 = " + price);
        }
    }
}